/**
 * 给你一个整数 columnNumber ，返回它在 Excel 表中相对应的列名称。
 * 例：A -> 1， B -> 2，……，AA -> 27
 **/

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;


/**
 * Solution 1:
 * 这题本质上是26进制转化，利用余数转ASCII码可以得到对应字母
 * 但取余操作会带来一个问题，Z -> 26，但取余操作会把结果算成0
 * 所以对Z的余数0要单独处理，加上26
 * 但这只能解决Z这一位的问题，多位数的情况下这样计算还会影响其他位数的结果
 * 如 26=1余0会被转成AZ，正确答案是Z; 52=2余0会被转成BZ，正确答案是AZ
 * 按 26进制思路应该是0余26和1余26
 * 所以这种情况还要对自除结果-1
 **/
class Solution_1 {
public:
    string convertToTitle(int columnNumber) {
        string excelstr;
        while (columnNumber > 0)
        {
            int tmp = columnNumber % 26;
            char ch;
            if(tmp == 0){
                // int ASCII转字符
                ch = (char)(tmp + 90);
                columnNumber = columnNumber / 26 - 1;
            }
            else{
                ch = (char)(tmp + 64);
                columnNumber /= 26;
            }
            // 因为string是一个指针，存储的值是所指向的地址，而char型存储的是内容
            // 所以不可以直接用赋值号赋值进行类型转换，利用string构造函数是一种转换方式
            string str(1, ch);
            // 在string指定位置插入字符串
            excelstr.insert(0, str);
            
        }
        return excelstr;
    }
};

/**
 * Solution 2：代码结构优化
 * 对于一般性的进制转换题目，只需要不断地对 columnNumbercolumnNumber 进行 % 运算取得最后一位，
 * 然后对 columnNumbercolumnNumber 进行 / 运算，将已经取得的位数去掉，直到 columnNumbercolumnNumber 为 0 即可。
 * 一般性的进制转换题目无须进行额外操作，是因为我们是在「每一位数值范围在 [0,x)」的前提下进行「逢 xx 进一」。
 * 但本题需要我们将从 11 开始，因此在执行「进制转换」操作前，我们需要先对 columnNumbercolumnNumber 执行减一操作，从而实现整体偏移。
 * 实现 A-Z : 1-26 -> A-Z : 0-25
 **/
class Solution {
public:
    string convertToTitle(int columnNumber) {
        string ans;
        while (columnNumber > 0) {
            columnNumber -- ;
            int tmp = columnNumber % 26;
            // 计算是从低位求解到高位， 把每次的结果插入到字符串末尾，得到所有字符后再转置就是最后结果
            // 整数+字符ASCII码得到新的字符的ASCII码
            ans += tmp + 'A';
            columnNumber /= 26;
        }
        reverse(ans.begin(), ans.end());
        return ans;
    }
};